#include <osapi.h>
#include <user_interface.h>
#include <espconn.h>
#include <mem.h>
#include "driver/uart.h"
#include "http.h"
#include "driver/gpio16.h"
#include "main.h"
#include "led.h"
// Create a timer
static os_timer_t periodic_timer;

// Timer callback function
void ICACHE_FLASH_ATTR timer_callback(void *arg) {
    send_http_request();
}


// WiFi event handler
void ICACHE_FLASH_ATTR wifi_event_handler_cb(System_Event_t *event) {
    if (event->event == EVENT_STAMODE_GOT_IP) {
        os_printf("Connected to WiFi 666\n");
        stopFlash();
        bool a = wifi_set_sleep_type(MODEM_SLEEP_T);
        os_printf("wifi_set_sleep_type %d\n", a);
        // Set up the timer to call send_http_request every minute
        os_timer_disarm(&periodic_timer);
        os_timer_setfn(&periodic_timer, (os_timer_func_t *)timer_callback, NULL);
        os_timer_arm(&periodic_timer, 1000 * 60 * 5, 1); // 60000 ms = 1 minute
        send_http_request();
        pinInit();
    }
}

void ICACHE_FLASH_ATTR pinInit(void) {

    PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO0_U, FUNC_GPIO0); //上电时需为高电平
    // PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0TXD_U, FUNC_GPIO1); //默认用于 UART TX 设置为gpio后，控制台无法输出内容
    PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO2_U, FUNC_GPIO2); //上电时需为高电平
    PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0RXD_U, FUNC_GPIO3); //默认用于 UART RX
    PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO4_U, FUNC_GPIO4); //	无限制
    PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO5_U, FUNC_GPIO5); //	无限制
    // GPIO6~11	 专用于 SPI Flash
    PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDI_U, FUNC_GPIO12); //无限制
    PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTCK_U, FUNC_GPIO13); //无限制
    PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTMS_U, FUNC_GPIO14); //无限制
    PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDO_U, FUNC_GPIO15); //上电时需为低电平
    //与其他 IO ⼝不同，GPIO16(XPD_DCDC) 不属于通⽤ GPIO 模块，它属于 RTC 模块，可以
    // ⽤来在深度睡眠时候唤醒整个芯⽚，可以配置为输⼊或者输出模式，但⽆法触发 IO 中
    // 断。使⽤接⼝如下：
    // • gpio16_output_conf(void)
    // 将 GPIO16 配置为输出模式。
    // • gpio16_output_set(uint8 value)
    // 从 GPIO16 输出⾼电平／低电平，需要先配置为输出模式。
    // • gpio16_input_conf(void)
    // 将 GPIO16 配置为输⼊模式。
    // • gpio16_input_get(void)
    // 读取 GPIO16 的输⼊电平状态，需要先配置为输⼊模式。
    gpio16_input_conf();

    PIN_PULLUP_DIS(PERIPHS_IO_MUX_GPIO0_U); //0每个引脚的寄存器，第七位都是上拉电阻开关
    PIN_PULLUP_DIS(PERIPHS_IO_MUX_U0TXD_U); //1
    PIN_PULLUP_DIS(PERIPHS_IO_MUX_GPIO2_U); //2
    PIN_PULLUP_DIS(PERIPHS_IO_MUX_U0RXD_U); //3
    PIN_PULLUP_DIS(PERIPHS_IO_MUX_GPIO4_U); //4
    PIN_PULLUP_DIS(PERIPHS_IO_MUX_GPIO5_U); //5
    PIN_PULLUP_DIS(PERIPHS_IO_MUX_MTDI_U); //12
    PIN_PULLUP_DIS(PERIPHS_IO_MUX_MTCK_U); //13
    PIN_PULLUP_DIS(PERIPHS_IO_MUX_MTMS_U); //14
    PIN_PULLUP_DIS(PERIPHS_IO_MUX_MTDO_U); //15

    // void	gpio_output_set(
    // 				uint32	set_mask,	
    // 				uint32	clear_mask,	
    // 				uint32	enable_mask,	
    // 				uint32	disable_mask
    // )
    // 参数
    // uint32	set_mask：设置输出为⾼的位，对应位为1，输出⾼，对应位为0，不改变状态
    // uint32	clear_mask：设置输出为低的位，对应位为1，输出低，对应位为0，不改变状态
    // uint32	enable_mask：设置使能输出的位
    // uint32	disable_mask：设置使能输⼊的位

    gpio_output_set(0,0,0,0xffff);//将1-16引脚都设置为输入模式
}


void ICACHE_FLASH_ATTR beginWifi(void)
{
    UART_SetBaudrate(0, 115200); //针对单个设置
    //uart_init(115200, 115200); //设置双串口
    os_printf("SDK version:%s\n", system_get_sdk_version());

    // 设置2脚，led脚为gpio模式
    PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO2_U, FUNC_GPIO2);
    beginFlash(-1);
    // Set WiFi mode and connect to WiFi
    wifi_set_opmode(STATION_MODE);
    struct station_config stationConf;
    os_memset(&stationConf, 0, sizeof(struct station_config));
    os_sprintf(stationConf.ssid, WIFI_SSID);
    os_sprintf(stationConf.password, WIFI_PASS);
    wifi_station_set_config(&stationConf);

    // Register the WiFi event handler
    wifi_set_event_handler_cb(wifi_event_handler_cb);
}


void delay()
{
    os_delay_us(65535); //65ms
    os_delay_us(65535); //65ms
    os_delay_us(65535); //65ms
}

void ICACHE_FLASH_ATTR sleepTest(void)
{
    // 设置2脚，led脚为gpio模式
    PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO2_U, FUNC_GPIO2);
    GPIO_OUTPUT_SET(2, 0);//亮起led

    delay();
    wifi_set_opmode(NULL_MODE);

    delay();
    pinInit();

    delay();
    system_deep_sleep(0);
}


// Initialization function
void ICACHE_FLASH_ATTR user_init(void) {
    // sleepTest();
    beginWifi();
}
